package com.start.oss;

import cn.hutool.core.annotation.AnnotationUtil;
import com.start.oss.filters.StartOSSFilter;
import com.start.oss.filters.StartOSSFilterOrder;
import com.start.oss.service.StartSysOssService;
import com.start.oss.storage.StartOssStorageService;
import com.start.security.StartSecurityConfig;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Data
@Slf4j
@Configuration
@ComponentScan({"com.start.oss.**"})
@MapperScan({"com.start.oss.mappers.**"})
@ConfigurationProperties(prefix = "start.upload")
@AutoConfigureAfter(StartSecurityConfig.class)
public class StartOssAutoConfiguration implements WebMvcConfigurer {

    private String masterStorageType;


    private final Map<String, StartOssStorageService> ossStorageServiceMap;


    private final Map<String, StartOSSFilter> filterMap;


    private final StartSysOssService startSysOssService;

    @Autowired
    private StartOssLocalStorageConfig startOssLocalStorageConfig;


    public StartOssAutoConfiguration(Map<String, StartOssStorageService> ossStorageServiceMap,
                                     Map<String, StartOSSFilter> filterMap,
                                     StartSysOssService startSysOssService) {
        this.ossStorageServiceMap = ossStorageServiceMap;
        this.filterMap = filterMap;
        this.startSysOssService = startSysOssService;
    }


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (startOssLocalStorageConfig.isEnable()) {
            String localFilePath = startOssLocalStorageConfig.getRootPath();
            File file = new File(localFilePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            localFilePath = file.getAbsolutePath() + File.separator;
            String rootPublicRootUrl = startOssLocalStorageConfig.getRootUrl() + "/**";
            rootPublicRootUrl = rootPublicRootUrl.replaceAll("/{2,}", "/");
            log.info(String.format("静态资源映射：\nurl:%s\n文件夹：%s", rootPublicRootUrl, localFilePath));
            registry.addResourceHandler(rootPublicRootUrl).addResourceLocations("file:" + localFilePath);
        }
    }


    @Bean
    public StartOssService startOssService() {
        final List<StartOSSFilter> filter = getFilters();
        return new StartOssWrapper(ossStorageServiceMap, filter, startSysOssService, masterStorageType);
    }

    private List<StartOSSFilter> getFilters() {
        if (filterMap == null || filterMap.size() < 1) return null;
        final ArrayList<StartOSSFilter> startOSSFilters = new ArrayList<>(filterMap.values());
        return startOSSFilters.stream().sorted(Comparator.comparing((e1) -> {

            final StartOSSFilterOrder annotation1 = AnnotationUtil.getAnnotation(e1.getClass(), StartOSSFilterOrder.class);
            if (annotation1 != null) {
                return StartOssConstant.DEFAULT_FILTER_ORDER;
            }
            return annotation1.value();
        })).collect(Collectors.toList());
    }

}
